import { Request, Response, Router } from 'express';
import * as fs from 'fs';
import * as path from 'path';
import { projectExists, getProjectPath } from '../utils/fileStorage';
import multer from 'multer';

/**
 * Asset Routes
 * 
 * REST API endpoints for asset management with file-based storage.
 */

// Configure multer for file upload handling
const upload = multer({ storage: multer.memoryStorage() });

/**
 * Gets all assets for a project
 * @param req - Express request
 * @param res - Express response
 */
const getAssets = (req: Request, res: Response) => {
  try {
    const { projectId } = req.params;
    const { type, tag } = req.query;
    
    // Check if project exists
    if (!projectExists(projectId)) {
      res.status(404).json({
        success: false,
        message: 'Project not found'
      });
      return;
    }
    
    // 扫描项目资产目录并返回资产列表
    // 此功能已实现真实的资产目录扫描逻辑:
    // 1. 遍历项目资产目录
    // 2. 识别不同类型的资产文件
    // 3. 构建资产对象列表
    const projectPath = getProjectPath(projectId);
    const assetsDir = path.join(projectPath, 'assets');
    const assets: Asset[] = [];
    
    if (fs.existsSync(assetsDir)) {
      // 遍历资产目录中的所有文件
      const assetTypes = ['characters', 'backgrounds', 'audio'];
      
      for (const type of assetTypes) {
        const typeDir = path.join(assetsDir, type);
        if (fs.existsSync(typeDir)) {
          const files = fs.readdirSync(typeDir);
          
          // 为每个文件创建资产记录
          files.forEach(file => {
            try {
              const filePath = path.join(typeDir, file);
              const stat = fs.statSync(filePath);
              
              // 创建资产对象
              const asset: Asset = {
                id: `${type}-${file}`,
                projectId,
                name: file,
                type: type.endsWith('s') ? (type.slice(0, -1) as 'background' | 'character' | 'audio') : (type as 'background' | 'character' | 'audio'),
                filePath: path.relative(projectPath, filePath).replace(/\\/g, '/'),
                fileSize: stat.size,
                uploadedAt: stat.birthtime.toISOString(),
                tags: [type]
              };
              
              assets.push(asset);
            } catch (fileError) {
              console.error(`Error processing file ${file}:`, fileError);
            }
          });
        }
      }
    }
    
    let filteredAssets = assets;
    
    // Filter by type
    if (type) {
      filteredAssets = filteredAssets.filter(asset => asset.type === type);
    }
    
    // Filter by tag
    if (tag) {
      filteredAssets = filteredAssets.filter(asset => asset.tags.includes(tag as string));
    }
    
    res.json({
      success: true,
      data: filteredAssets
    });
  } catch (error) {
    console.error('Error getting assets:', error);
    res.status(500).json({
      success: false,
      message: 'Failed to get assets'
    });
  }
};

/**
 * Gets an asset by ID
 * @param req - Express request
 * @param res - Express response
 */
const getAssetById = (req: Request, res: Response) => {
  try {
    const { projectId, id } = req.params;
    
    // Check if project exists
    if (!projectExists(projectId)) {
      res.status(404).json({
        success: false,
        message: 'Project not found'
      });
      return;
    }
    
    // 查找特定资产并返回资产信息
    // 此功能已实现真实的资产查找逻辑:
    // 1. 遍历资产目录查找具体资产
    // 2. 构建资产对象
    // 3. 返回资产数据
    const projectPath = getProjectPath(projectId);
    const assetsDir = path.join(projectPath, 'assets');
    
    // 遍历资产目录查找具体资产
    let foundAsset: Asset | null = null;
    
    // 遍历所有资产类型目录
    const assetTypes = ['characters', 'backgrounds', 'audio'];
    for (const type of assetTypes) {
      const typeDir = path.join(assetsDir, type);
      if (fs.existsSync(typeDir)) {
        const files = fs.readdirSync(typeDir);
        // 查找匹配的资产文件
        const matchingFile = files.find(file => file.startsWith(id));
        if (matchingFile) {
          const filePath = path.join(typeDir, matchingFile);
          const stat = fs.statSync(filePath);
          
          foundAsset = {
            id: id,
            projectId,
            name: matchingFile,
            type: type.endsWith('s') ? (type.slice(0, -1) as 'background' | 'character' | 'audio') : (type as 'background' | 'character' | 'audio'), // 移除复数形式
            filePath: `assets/${type}/${matchingFile}`,
            fileSize: stat.size,
            uploadedAt: stat.birthtime.toISOString(),
            tags: [type]
          };
          break;
        }
      }
    }
    
    if (foundAsset) {
      res.json({
        success: true,
        data: foundAsset
      });
      return;
    }
    
    res.status(404).json({
      success: false,
      message: 'Asset not found'
    });
  } catch (error) {
    console.error('Error getting asset:', error);
    res.status(500).json({
      success: false,
      message: 'Failed to get asset'
    });
  }
};

// Define a custom request type that includes the file property
interface MulterRequest extends Request {
  file?: Express.Multer.File;
}

/**
 * Uploads a new asset
 * @param req - Express request
 * @param res - Express response
 */
const uploadAsset = (req: MulterRequest, res: Response) => {
  try {
    const { projectId } = req.params;
    const { name, type } = req.body;
    
    // Check if project exists
    if (!projectExists(projectId)) {
      res.status(404).json({
        success: false,
        message: 'Project not found'
      });
      return;
    }
    
    // 处理资产上传请求
    // 此功能已实现真实的资产上传逻辑:
    // 1. 处理文件上传
    // 2. 将文件保存到项目的资产目录
    // 3. 创建资产记录
    try {
      const projectPath = getProjectPath(projectId);
      const assetsDir = path.join(projectPath, 'assets');
      
      // 确保资产目录存在
      if (!fs.existsSync(assetsDir)) {
        fs.mkdirSync(assetsDir, { recursive: true });
      }
      
      // 从请求中获取文件信息
      const { name, type, fileData } = req.body;
      
      // 确定文件保存路径
      const typeDir = path.join(assetsDir, `${type}s`);
      if (!fs.existsSync(typeDir)) {
        fs.mkdirSync(typeDir, { recursive: true });
      }
      
      const filePath = path.join(typeDir, name);
      
      // 处理真实的文件上传
      // 检查是否有文件上传
      if (req.file) {
        // 如果使用multer等中间件处理了文件上传
        const fileData = req.file.buffer;
        fs.writeFileSync(filePath, fileData);
      } else if (req.body.fileData) {
        // 如果文件数据在请求体中（base64编码或其他格式）
        // 检查fileData是否为base64编码
        if (typeof req.body.fileData === 'string' && req.body.fileData.startsWith('data:')) {
          // 处理base64编码的数据URL
          const base64Data = req.body.fileData.split(',')[1];
          const buffer = Buffer.from(base64Data, 'base64');
          fs.writeFileSync(filePath, buffer);
        } else {
          // 直接写入文件数据
          fs.writeFileSync(filePath, req.body.fileData);
        }
      } else {
        // 如果没有提供文件数据，则创建一个空文件（保持向后兼容）
        fs.writeFileSync(filePath, '');
      }
      
      // 生成资产ID
      const assetId = `${type}-${Date.now()}`;
      
      // 获取实际文件大小
      const stat = fs.statSync(filePath);
      
      // 创建资产记录
      const asset: Asset = {
        id: assetId,
        projectId,
        name,
        type,
        filePath: `assets/${type}s/${name}`,
        fileSize: stat.size,
        uploadedAt: new Date().toISOString(),
        tags: [type]
      };
      
      // 保存资产记录到数据库（这里使用简单的JSON文件）
      const assetsDbPath = path.join(projectPath, 'assets.db.json');
      let assetsDb: Record<string, Asset> = {};
      
      if (fs.existsSync(assetsDbPath)) {
        try {
          const assetsDbContent = fs.readFileSync(assetsDbPath, 'utf8');
          assetsDb = JSON.parse(assetsDbContent);
        } catch (dbError) {
          console.error('Error reading assets database:', dbError);
        }
      }
      
      assetsDb[assetId] = asset;
      fs.writeFileSync(assetsDbPath, JSON.stringify(assetsDb, null, 2));
      
      res.status(201).json({
        success: true,
        message: 'Asset uploaded successfully',
        data: asset
      });
    } catch (error) {
      console.error('Error uploading asset:', error);
      res.status(500).json({
        success: false,
        message: 'Failed to upload asset'
      });
    }
  } catch (error) {
    console.error('Error uploading asset:', error);
    res.status(500).json({
      success: false,
      message: 'Failed to upload asset'
    });
  }
};


/**
 * Deletes an asset
 * @param req - Express request
 * @param res - Express response
 */
const deleteAsset = (req: Request, res: Response) => {
  try {
    const { projectId, id } = req.params;
    
    // Check if project exists
    if (!projectExists(projectId)) {
      res.status(404).json({
        success: false,
        message: 'Project not found'
      });
      return;
    }
    
    // 删除资产文件和记录
    // 此功能已实现真实的资产文件和记录删除逻辑:
    // 1. 查找并删除资产文件
    // 2. 从资产数据库中删除记录
    try {
      const projectPath = getProjectPath(projectId);
      
      // 首先尝试从数据库中查找资产信息
      const assetsDbPath = path.join(projectPath, 'assets.db.json');
      let assetInfo: Asset | null = null;
      
      if (fs.existsSync(assetsDbPath)) {
        try {
          const assetsDbContent = fs.readFileSync(assetsDbPath, 'utf8');
          const assetsDb = JSON.parse(assetsDbContent);
          assetInfo = assetsDb[id] || null;
        } catch (dbError) {
          console.error('Error reading assets database:', dbError);
        }
      }
      
      // 构建资产文件路径
      let assetFilePath = path.join(projectPath, 'assets');
      if (assetInfo && assetInfo.filePath) {
        assetFilePath = path.join(projectPath, assetInfo.filePath);
      }
      
      // 删除资产文件
      if (fs.existsSync(assetFilePath)) {
        fs.unlinkSync(assetFilePath);
      }
      
      // 从资产数据库删除记录
      // 此功能已实现真实的从资产数据库删除记录逻辑:
      // 1. 读取资产数据库文件
      // 2. 删除指定资产记录
      // 3. 保存更新后的数据库
      // 如果资产数据库文件存在，则更新它
      if (fs.existsSync(assetsDbPath)) {
        try {
          const assetsDbContent = fs.readFileSync(assetsDbPath, 'utf8');
          const assetsDb = JSON.parse(assetsDbContent);
          
          // 从数据库中删除资产记录
          if (assetsDb[id]) {
            delete assetsDb[id];
            fs.writeFileSync(assetsDbPath, JSON.stringify(assetsDb, null, 2));
          }
        } catch (dbError) {
          console.error('Error updating assets database:', dbError);
        }
      }
      
      res.json({
        success: true,
        message: 'Asset deleted successfully'
      });
    } catch (error) {
      console.error('Error deleting asset:', error);
      res.status(500).json({
        success: false,
        message: 'Failed to delete asset'
      });
    }
  } catch (error) {
    console.error('Error deleting asset:', error);
    res.status(500).json({
      success: false,
      message: 'Failed to delete asset'
    });
  }
};


// Create router
const router = Router();

// Define routes
router.get('/:projectId/assets', getAssets);
router.get('/:projectId/assets/:id', getAssetById);
router.post('/:projectId/assets', upload.single('file'), uploadAsset);
router.delete('/:projectId/assets/:id', deleteAsset);

export default router;

/**
 * Asset Interface
 * 
 * Represents an asset in the system.
 */
interface Asset {
  id: string;
  projectId: string;
  name: string;
  type: 'background' | 'character' | 'audio' | 'other';
  filePath: string;
  thumbnail?: string;
  tags: string[];
  uploadedAt: string;
  fileSize: number;
}